package com.yuyou.fn.common.util;

import com.alibaba.druid.util.StringUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import java.util.ArrayList;
import java.util.List;
import java.util.Random;

public class SignatureUtil {

	private static final Logger LOGGER = LoggerFactory.getLogger(SignatureUtil.class);

    /**
     * 校验签名是否一致
     * @param remoteSignature
     * @param params
     * @param appId
     * @param appKey
     * @param ts
     * @return true:一致, false:不一致
     */
    public static boolean validateApiSignature(String remoteSignature, List<Object> params, String appId, String appKey, Long ts) throws Exception{
        String salt = SignatureUtil.getSaltFromSignature(remoteSignature);
        String signature = SignatureUtil.getSignatureFromRemoteSignature(remoteSignature);
        String localSignature = SignatureUtil.generateLocalSignature(params, appId, appKey, ts, salt);

        LOGGER.info("盐值：{}，远程签名：{}", salt, signature);
        return StringUtils.equals(localSignature, signature);
    }

    /**
     * 获取本地签名
     * 格式: {盐值}{参数1}{参数2}{参数x...}{systemType}{appSecret}{ts}{盐值}
     * @param params 业务参数
     * @param appId 业务系统id
     * @param appKey 业务系统key
     * @param ts 当前时间毫秒
     * @return
     * @throws Exception
     * 测试完改回private
     */
    public static String generateLocalSignature(List<Object> params, String appId, String appKey, Long ts, String salt) {
        if(params == null){
            params = new ArrayList<Object>();
        }

        StringBuilder originString = new StringBuilder();
        originString.append(salt);
        for(Object param : params) {
            String paramString = "";
            if(param != null){
                paramString = param.toString();
            }
            originString.append(paramString);
        }
        originString.append(appId);
        originString.append(appKey);
        originString.append(ts);
        originString.append(salt);

        String localSignature  = MD5Helper.MD5(originString.toString());
        LOGGER.info("获取API签名，签名前字符串为：{}，本地签名：{}", originString.toString(), localSignature);

        return localSignature;
    }

    private static String getSaltFromSignature(String Signature) {
        StringBuilder salt = new StringBuilder();

        salt.append(Signature.substring(10, 14));
        salt.append(Signature.substring(20, 24));
        salt.append(Signature.substring(30, 34));
        salt.append(Signature.substring(44, 48));

        return salt.toString();
    }

    private static String getSignatureFromRemoteSignature(String Signature) {
        StringBuilder md5 = new StringBuilder();

        md5.append(Signature.substring(0, 10));
        md5.append(Signature.substring(14, 20));
        md5.append(Signature.substring(24, 30));
        md5.append(Signature.substring(34, 44));

        return md5.toString();
    }
    
    public static String generateSalt(int len) {
		char [] array = {'a','b','c','d','e','f','g','h','i','j','k','l','m','n','o','p','q','r','s','t','u','v','x','y','z','1','2','3','4','5','6','7','8','9','0'} ;
        Random random = new Random() ;
        StringBuilder salt = new StringBuilder();
        for(int i=0 ;i< len;i++) {
        	int index = random.nextInt(array.length) ;
        	salt.append(array[index]) ;
        }
        return salt.toString().toUpperCase();
    }
    
    public static String generateRemoteSignature(String salt,String signature) {
        StringBuilder md5 = new StringBuilder();
        
        md5.append(signature.substring(0, 10));
        md5.append(salt.substring(0, 4)) ;
        md5.append(signature.substring(10, 16));
        md5.append(salt.substring(4, 8)) ;
        md5.append(signature.substring(16, 22));
        md5.append(salt.substring(8, 12)) ;
        md5.append(signature.substring(22, 32));
        md5.append(salt.substring(12,16)) ;

        return md5.toString();
    }


//    public static void main(String[] args) throws Exception{
//
////        1、业务系统生成一个16位大写的随机数盐值
////        ECPNECPNECPNECPN
//
////        2、按{参数1}{参数2}{参数…}{systemType}{appSecret}{ts}的格式拼接得到需要参与签名的参数值
////        15918737891TMSabcd12341528884458000
//
////        3、按{盐值}{参数值}{盐值}的顺序对整个字符串做MD5加密，得到一个32位大写的MD5摘要。
////        TMSTMSTMSTMSTMS115918737891TMSabcd12341528884458000TMSTMSTMSTMSTMS1
////        1F191720BEF4C8F2D5938D0DBBE0853D
//
////        4、随后将盐值平均分割为4个4位的字符串，将MD5摘要分割为4个分别为10位、6位、6位、10位的字符串，按照{MD5摘要1}{盐值1}{MD5摘要2}{盐值2}{MD5摘要3}{盐值3}{MD5摘要4}{盐值4}格式拼接得到最终的48位signature。
////        1F191720BETMSTF4C8F2MSTMD5938DSTMS0DBBE0853DTMS1
//
//
//        String phone = "15918737891";
//        String studentName = "hzyxx";
//        String studentCode = "hzw001";
//        List<Object> paramList = Arrays.asList(phone, studentName, studentCode);
//
//        String systemType = "TMS";
//        String appSecret = "abcd1234";
//        long ts = 1535364891638L;
//
//        String remoteSignature = "D7D3AA87DAB275B3521C8C51509E1A4BA37DC794D25A486C";
//        System.out.println("结果："+SignatureUtil.validateApiSignature(remoteSignature, paramList, systemType, appSecret, ts));
//
//    }

}
